home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 2 / Gold Medal Software Volume 2 (Gold Medal) (1994).iso / prog / asm_0_m.arj / EXECOM.ASM < prev    next >
Assembly Source File  |  1988-03-19  |  15KB  |  313 lines

  1. Title  EXECOM: convert an .EXE file to a .COM file
  2.  
  3. comment !
  4.    EXECOM 1.1  Copyright (c) 1988  Thomas G. Hanlin III
  5.  
  6.          1712 Maple Hill Pl.
  7.          Alexandria VA 22152
  8.  
  9.    Note: This was assembled with the excellent OPTASM assembler.  Slight
  10.    modifications may be needed in the way of JMP pointers, MOV size
  11.    pointers, and so forth if you're using MASM (yuck).
  12. !
  13.  
  14.  
  15. Sseg           segment byte stack 'prog'    ; dummy stack segment
  16. Sseg           ends
  17.  
  18.  
  19. Cseg           segment byte public 'prog'
  20.                assume         cs:Cseg, ds:Cseg, ss:Sseg
  21.  
  22.                org            100h
  23.  
  24. MAIN           proc           far
  25.                xor            dx,dx              ; number of parms
  26.                mov            cx,dx
  27.                mov            EXITCODE,cl        ; assume no errors
  28.                mov            cl,ds:[0080h]      ; get parm length
  29.                jcxz           Inform             ;   inform 'em if no parms
  30.                mov            si,0081h
  31.                cld
  32.  
  33. ScanParms:     lodsb                             ; get a command-line char
  34.                cmp            al," "             ; is it a space?
  35.                jbe            ScanLoop2          ;   yes, ignore it
  36.                mov            di,offset OUTFILE  ; assume output file name
  37.                inc            dx                 ; increment parm number
  38.                cmp            dx,2               ; check it
  39.                ja             Inform             ;   too large, inform 'em
  40.                je             SaveFileName       ;   default OUTFILE is ok
  41.                mov            di,offset INFILE   ; input file name (string)
  42. SaveFileName:  stosb                             ; store a char of the filename
  43.                dec            cx                 ; are we done yet?
  44.                jz             ScanDone           ;   yes, exit
  45.                lodsb                             ; get another char
  46.                cmp            al," "             ; is it blank?
  47.                ja             SaveFileName       ;   no, must be a filename chr
  48. ScanLoop2:     loop           ScanParms          ;   keep looking for parms
  49.  
  50. ScanDone:      or             dx,dx              ; any parms?
  51.                jz             Inform             ;   no, inform 'em
  52.                dec            dx                 ; only one parm?
  53.                jnz            ChangeExts         ;   no, go change extensions
  54.                mov            si,offset INFILE   ; input file name
  55.                mov            di,offset OUTFILE  ; output file name
  56. DupeFile:      lodsb                             ; get an input char
  57.                or             al,al              ; is it null?
  58.                jz             ChangeExts         ;   yes, done- change exts
  59.                stosb                             ; store char in output name
  60.                jmp            DupeFile           ;   keep on truckin'
  61.  
  62. Inform:        mov            dx,offset INFORMATION
  63.                mov            ah,9
  64.                int            21h
  65.                mov            EXITCODE,255
  66.                jmp            Abort
  67.  
  68. ChangeExts:    mov            si,offset INFILE   ; input file name
  69. Change1:       lodsb                             ; get a char
  70.                or             al,al              ; are we done?
  71.                jz             AddExtIn1          ;   yes, needs extension
  72.                cmp            al,"."             ; is it a period?
  73.                jne            Change1            ;   no, keep looking
  74.  
  75. ChangeExt2:    mov            si,offset OUTFILE  ; output file name
  76. Change2:       lodsb                             ; get a char
  77.                or             al,al              ; are we done?
  78.                jz             AddExtIn2          ;   yes, needs extension
  79.                cmp            al,"."             ; is it a period?
  80.                jne            Change2            ;   no, keep looking
  81.                lodsw                             ; is the extension ".EXE"?
  82.                cmp            ax,"XE"            ;
  83.                jne            OpenFiles          ;   no, go open the files
  84.                lodsb                             ;
  85.                cmp            al,"E"             ;
  86.                jne            OpenFiles          ;   no, go open the files
  87.                sub            si,3               ; pretend there's no ext
  88.  
  89. AddExtIn2:     dec            si                 ; move back to the first null
  90.                mov            di,si
  91.                mov            ax,"C."            ; install a ".COM"...
  92.                stosw                             ; ...file extension
  93.                mov            ax,"MO"            ;
  94.                stosw                             ;
  95.                jmp            OpenFiles
  96.  
  97. AddExtIn1:     dec            si                 ; move back to the first null
  98.                mov            di,si
  99.                mov            ax,"E."            ; install an ".EXE"...
  100.                stosw                             ; ...file extension
  101.                mov            ax,"EX"            ;
  102.                stosw                             ;
  103.                jmp            ChangeExt2
  104.  
  105.  
  106. ;------------------- Everything's set up, let's open the files ----------------
  107.  
  108.  
  109. OpenFiles:     mov            ax,3D00h           ; open file for read
  110.                mov            dx,offset INFILE   ; input file name
  111.                int            21h
  112.                jnc            InputOpenOk
  113.                mov            bl,1
  114.                jmp            ErrVector
  115.  
  116. InputOpenOk:   mov            INHANDLE,ax        ; save input file handle
  117.                mov            bx,ax
  118.                mov            ah,3Fh             ; read from file
  119.                mov            cx,24              ; 24 bytes
  120.                mov            dx,offset LASTBYTE ; data buffer
  121.                int            21h
  122.                jnc            ReadOk
  123.                mov            bl,9
  124.                jmp            ErrVector
  125.  
  126. ReadOk:        mov            si,dx
  127.                mov            di,offset EXE_SIG
  128.                movsw                             ; set EXE_SIG
  129.                movsw                             ; set EXE_EXCESS
  130.                movsw                             ; set EXE_PAGES
  131.                movsw                             ; set EXE_RELOCCOUNT
  132.                movsw                             ; set EXE_HDRSIZE
  133.                add            si,4
  134.                movsw                             ; set EXE_SS
  135.                movsw                             ; set EXE_SP
  136.                add            si,2
  137.                movsw                             ; set EXE_IP
  138.                movsw                             ; set EXE_CS
  139.  
  140.  
  141.                mov            bl,3               ; default error code
  142.                cmp            EXE_SIG,"ZM"       ; is the signature ok?
  143.                jne            ErrVector          ;   nope, error
  144.                inc            bl                 ; inc error code
  145.                cmp            EXE_RELOCCOUNT,0   ; any relocations needed?
  146.                jne            ErrVector          ;   yes, error
  147.                inc            bl                 ; inc error code
  148.                cmp            EXE_SS,0           ; is there a defined SS?
  149.                jne            ErrVector          ;   yes, error
  150.                cmp            EXE_SP,0           ; is there a defined SP?
  151.                jne            ErrVector          ;   yes, error
  152.                inc            bl                 ; inc error code
  153.                cmp            EXE_CS,0           ; is there a defined CS?
  154.                jne            ErrVector          ;   yes, error
  155.                inc            bl                 ; inc error code
  156.                cmp            EXE_IP,0           ; is the IP = 0?
  157.                je             ChecksOk           ;   yes, it's ok
  158.                cmp            EXE_IP,0100h       ; is the IP = 0100h?
  159.                jne            ErrVector          ;   no, error
  160.  
  161. ChecksOk:      mov            bx,EXE_HDRSIZE
  162.                mov            cl,4
  163.                shl            bx,cl              ; CodeStart in BX ****
  164.                mov            ax,EXE_PAGES
  165.                dec            ax
  166.                mov            cx,512
  167.                mul            cx
  168.                sub            ax,bx
  169.                sbb            dx,0               ; CodeSize in DX:AX ***
  170.                mov            cx,EXE_EXCESS
  171.                jcxz           NoDribble
  172.                add            ax,cx
  173.                jmp            GotCodeSize
  174. NoDribble:     add            ax,512
  175. GotCodeSize:   adc            dx,0
  176.                or             dx,dx              ; is it too large?
  177.                jz             CheckIP            ;   no, keep on truckin'
  178.                mov            bl,8
  179. ErrVector:     jmp            ErrorExit
  180.  
  181. CheckIP:       push           ax
  182.                cmp            EXE_IP,0100h       ; is IP right for .COM files?
  183.                je             IPok               ;   yes...
  184.                mov            dx,offset WARNING
  185.                mov            ah,9               ; display warning message
  186.                int            21h
  187. IPok:          mov            dx,bx              ; CodeStart
  188.                xor            cx,cx
  189.                add            dx,EXE_IP
  190.                adc            cx,cx
  191.                mov            bx,INHANDLE
  192.                mov            ax,4200h           ; move file ptr from start
  193.                int            21h
  194.                mov            ah,3Ch             ; create file for write
  195.                mov            dx,offset OUTFILE  ; output file name
  196.                xor            cx,cx              ; normal file attribute
  197.                int            21h
  198.                pop            si
  199.                jnc            OutputOpenOk
  200.                mov            bl,2
  201.                jmp            ErrVector
  202. OutputOpenOk:  mov            OUTHANDLE,ax       ; save output file handle
  203.                sub            si,EXE_IP          ; ignore IP bytes
  204.                mov            dx,offset LASTBYTE ; buffer location
  205.                mov            cx,32 * 1024       ; buffer size: 32K
  206.  
  207.  
  208. ; ----------------- Just copy the code from the EXE to the COM file -----------
  209.  
  210.  
  211. WriteLoop:     or             si,si
  212.                jz             Done
  213.                cmp            si,cx
  214.                ja             ReadBlock
  215.                mov            cx,si
  216. ReadBlock:     mov            ah,3Fh             ; read from file
  217.                mov            bx,INHANDLE
  218.                int            21h
  219.                jc             ReadError
  220.                mov            ah,40h             ; write to file
  221.                mov            bx,OUTHANDLE
  222.                int            21h
  223.                jc             WriteError
  224.                sub            si,cx
  225.                jmp            WriteLoop
  226.  
  227. ReadError:     mov            bl,9
  228.                jmp            ErrorExit0
  229. WriteError:    mov            bl,10
  230.  
  231.  
  232. ;---------------------------- Error exit handler ------------------------------
  233.  
  234.  
  235. ErrorExit0:    push           bx
  236.                mov            ah,3Eh             ; close a file
  237.                mov            bx,OUTHANDLE       ; ...output file
  238.                int            21h
  239.                pop            bx
  240.  
  241. ErrorExit:     mov            EXITCODE,bl
  242.                mov            ah,9               ; display error message
  243.                mov            dx,offset FATALERR ; "Fatal error: "
  244.                int            21h
  245.                mov            si,offset CANTOPEN ; first error message
  246. CheckErr:      dec            bl                 ; is it the error msg we want?
  247.                jz             GotError           ;   yes, got it
  248. FindErr:       lodsb                             ; get a char
  249.                cmp            al,"$"             ; end of message?
  250.                jne            FindErr            ;   no, keep looking
  251.                jmp            CheckErr           ;   see if it's the right one
  252. GotError:      mov            dx,si              ; pointer to error message
  253. ErrDone:       mov            ah,9
  254.                int            21h
  255.                cmp            EXITCODE,1         ; did we open the input file?
  256.                je             Abort              ;   no, don't close or delete
  257.  
  258. Done:          mov            ah,3Eh             ; close a file
  259.                mov            bx,INHANDLE        ; input file
  260.                int            21h
  261.                cmp            EXITCODE,0         ; successful conversion?
  262.                jnz            Abort              ;   no, just exit
  263.                mov            ah,41h             ; delete file
  264.                mov            dx,offset INFILE   ; ...the original input file
  265.                int            21h
  266. Abort:         mov            ah,4Ch             ; terminate program
  267.                mov            al,EXITCODE        ; error exit code
  268.                int            21h
  269. MAIN           endp
  270.  
  271.  
  272. WARNING        db "WARNING: The default IP is not 0100h.",13,10
  273.                db "The output file will not be executable.",13,10,"$"
  274.  
  275. FATALERR       db "Fatal error: $"
  276. CANTOPEN       db "Unable to open input file",13,10,"$"
  277. CANTMAKE       db "Unable to create output file",13,10,"$"
  278. BADSIG         db "Input file is not a valid .EXE file",13,10,"$"
  279. RELITEMS       db "There are items requiring relocation",13,10,"$"
  280. BADSTACK       db "A stack is defined",13,10,"$"
  281. BADCSEG        db "A code segment is defined",13,10,"$"
  282. BADCOFS        db "The code offset is neither 0 nor 0100h",13,10,"$"
  283. TOOBIG         db "File is too large (.COM would be over 64K)",13,10,"$"
  284. CANTREAD       db "Unable to read input file",13,10,"$"
  285. CANTWRITE      db "Unable to write to output file",13,10,"$"
  286.  
  287. INFORMATION    db "EXECOM 1.1  Copyright (c) 1988  Thomas G. Hanlin III",13,10
  288.                db "  Purpose: converts an .EXE file to a .COM file.",13,10
  289.                db "  Format : EXECOM inputfile[.EXE] [outputfile[.COM]]",13,10
  290.                db "$"
  291.  
  292. INHANDLE       dw ?
  293. OUTHANDLE      dw ?
  294. EXE_SIG        dw ?       ; EXE signature
  295. EXE_EXCESS     dw ?       ; bytes in excess of the 512b EXE_PAGES count
  296. EXE_PAGES      dw ?       ; code size, in 512b pages
  297. EXE_RELOCCOUNT dw ?       ; count of items in the relocation table
  298. EXE_HDRSIZE    dw ?       ; header size, in 16b paragraphs
  299. EXE_SS         dw ?       ; default SS
  300. EXE_SP         dw ?       ; default SP
  301. EXE_IP         dw ?       ; default IP
  302. EXE_CS         dw ?       ; default CS
  303.  
  304. EXITCODE       db ?       ; program error exit code
  305.  
  306. INFILE         db 80 dup (0)   ; input file name
  307. OUTFILE        db 80 dup (0)   ; output file name
  308.  
  309. LASTBYTE       db ?       ; final data byte, used as start of file buffer area
  310.  
  311. Cseg           ends
  312.                end            MAIN
  313.